package com.gitee.dupe.authority.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.gitee.dolt.boot.service.SuperServiceImpl;
import com.gitee.dolt.core.constant.RoleConstant;
import com.gitee.dupe.authority.dao.RoleMapper;
import com.gitee.dupe.authority.dto.UserRoleDTO;
import com.gitee.dupe.authority.entity.Resource;
import com.gitee.dupe.authority.entity.Role;
import com.gitee.dupe.authority.entity.RoleResource;
import com.gitee.dupe.authority.service.IResourceService;
import com.gitee.dupe.authority.service.IRoleResourceService;
import com.gitee.dupe.authority.service.IRoleService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author LYH
 * @since 2020-06-30
 */
@Service
@RequiredArgsConstructor
public class RoleServiceImpl extends SuperServiceImpl<RoleMapper, Role> implements IRoleService {

    private final IResourceService resourceService;
    private final IRoleResourceService roleResourceService;

    @Override
    public List<UserRoleDTO> findAllEnabledByUserId(Long userId) {
        Map<Long, List<UserRoleDTO>> map = mapEnabledByUserIds(Arrays.asList(userId));
        return map.get(userId) == null ? Collections.emptyList() : map.get(userId);
    }

    @Override
    public Map<Long, List<UserRoleDTO>> mapEnabledByUserIds(Collection<Long> userIds) {
        if (CollUtil.isEmpty(userIds)) {
            return Collections.emptyMap();
        }
        List<UserRoleDTO> userRoleDTOS = baseMapper.findAllEnabledByUserIds(userIds);
        return userRoleDTOS.stream().collect(Collectors.groupingBy(UserRoleDTO::getUserId));
    }

    @Override
    public Role getOneByName(String name) {
        return getOne(Wrappers.<Role>lambdaQuery().eq(Role::getName, name));
    }

    @Override
    public Role getDetail(Long id) {
        Role role = getById(id);
        List<Resource> resources = resourceService.findAllByRoleId(role.getId());
        role.setResources(resources);
        return role;
    }

    @Override
    public void grantResources(Long id, Set<Long> resourceIds) {
        if (resourceIds == null) {
            return;
        }
        List<RoleResource> roleResourcesDb = roleResourceService.findAllByRoleId(id);
        List<Long> removeResourceIds = new ArrayList<>();
        roleResourcesDb.forEach(e -> {
            Long resourceId = e.getResourceId();
            if (!resourceIds.contains(resourceId)) {
                removeResourceIds.add(resourceId);
            }
            Iterator<Long> perIterator = resourceIds.iterator();
            while (perIterator.hasNext()) {
                if (perIterator.next().equals(resourceId)) {
                    perIterator.remove();
                }
            }
        });
        roleResourceService.removeByRoleIdAndResourceIds(id, removeResourceIds);
        List<RoleResource> roleResources = resourceIds.stream().map(e -> new RoleResource().setRoleId(id).setResourceId(e)).collect(Collectors.toList());
        roleResourceService.saveBatch(roleResources);
    }

    @Override
    public void handlerDelete(List<Long> ids) {
        remove(Wrappers.<Role>lambdaQuery().ne(Role::getIdent, RoleConstant.SUPER_ADMIN).in(Role::getId, ids));
    }


}
